package com.atguigu.stack;

import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入计算表达式");
        String expression=scanner.next();
        String keepNum="";
        //数栈 能放十个数
        ArrayStack2 numStack=new ArrayStack2(10);
        //符号栈
        ArrayStack2 operStack=new ArrayStack2(10);
        int index=0;
        int num1=0;
        int num2=0;
        int oper=0;
        int res=0;
        char ch=' ';
        //开始扫描
        while (true){
            ch=expression.substring(index,index+1).charAt(0);
            //判断ch是符号还是数字
            if (operStack.isOper(ch)){
                //判断当前符号栈是否为空
                if (!operStack.isEmpty()) {
                    //如果符号栈中有运算符，就进行比较
                    //小于等于栈中操作符，就pop出两个数，再从栈中pop运算符，得到结果，入数栈，当前操作符入符号栈
                    if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        res = numStack.cal(num1, num2, oper);
                        //运算结果入数栈
                        numStack.push(res);
                        //操作符入数栈
                        operStack.push(ch);
                    }else {
                        operStack.push(ch);
                    }
                }else {
                        //为空直接入栈
                    operStack.push(ch);
                }
            }else {
                //如果是数直接入数栈
                //将字符转为数字,注意多位数
                keepNum+=ch;
                if (index==expression.length()-1){
                    numStack.push(Integer.parseInt(keepNum));
                }else {
                    if (numStack.isOper(expression.substring(index+1,index+2).charAt(0))){
                        numStack.push(Integer.parseInt(keepNum));//后一位是运算符，入栈
                        keepNum="";//重新清空
                    }
                }
            }
            index++;
            if (index==expression.length()){
                break;
            }
        }

        //表达式扫描完毕，按顺序出栈计算结果,可能有一个运算符在栈中
        while (true){
            //如果符号栈为空，则最后就是结果
            if (operStack.isEmpty()){
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = numStack.cal(num1, num2, oper);
            //运算结果入数栈
            numStack.push(res);
        }
        //将数栈最后数弹出就是结果
        System.out.println("表达式"+expression+"="+numStack.pop());
    }
}

class ArrayStack2{
    private int maxSize;
    private int[] stack;
    private int top=-1;

    public ArrayStack2(int maxSize){
        this.maxSize=maxSize;
        stack=new int[maxSize];
    }

    //栈满
    public boolean isFull(){
        return top==maxSize-1;
    }

    //栈空
    public boolean isEmpty(){
        return top==-1;
    }

    //返回栈顶的值但不弹出
    public int peek(){
        if (isEmpty()){
            throw new RuntimeException("栈空");
        }
        return stack[top];
    }

    public void push(int value){
        if (isFull()){
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top]=value;
    }

    public int pop(){
        if (isEmpty()){
//            System.out.println("栈空");
//            return 0;
            throw new RuntimeException("栈空");
        }
        int value= stack[top];
        top--;
        return value;
    }

    //遍历栈
    public void list(){
        if (isEmpty()){
            System.out.println("栈空");
            return;
        }
        for (int i = top; i >=0; i--) {
            System.out.println("stack["+i+"]="+stack[top]);
        }
    }
    //判断优先级
    public int priority(int oper){
        if (oper=='*'||oper=='/'){
            return 1;
        }else if (oper=='+'||oper=='-'){
            return 0;
        }else {
            return -1;
        }
    }
    //判断是不是一个运算符
    public boolean isOper(char val){
        return val=='+'||val=='-'||val=='*'||val=='/';
    }
    //计算方法
    public int cal(int num1,int num2,int oper){
        int res=0;//res 存放计算结果
        switch (oper){
            case '+':
                res=num1+num2;
                break;
            case '-':
                res=num2-num1;
                break;
            case '*':
                res=num1*num2;
                break;
            case '/':
                res=num2/num1;
                break;
            default:
                break;
        }
        return res;

    }
}